home *** CD-ROM | disk | FTP | other *** search
/ Aminet 30 / Aminet 30 (1999)(Schatztruhe)[!][Apr 1999].iso / Aminet / gfx / misc / gnuplot-3.7src.lha / gnuplot-3.7src / gnuplot-3.7.lha / gnuplot-3.7 / stdfn.c < prev    next >
C/C++ Source or Header  |  1998-11-20  |  9KB  |  389 lines

  1. #ifndef lint
  2. static char *RCSid = "$Id: stdfn.c,v 1.1 1998/05/19 18:05:02 ddenholm Exp $";
  3. #endif
  4.  
  5.  
  6. /* GNUPLOT - stdfn.c */
  7.  
  8. /*[
  9.  * Copyright 1986 - 1993, 1998   Thomas Williams, Colin Kelley
  10.  *
  11.  * Permission to use, copy, and distribute this software and its
  12.  * documentation for any purpose with or without fee is hereby granted,
  13.  * provided that the above copyright notice appear in all copies and
  14.  * that both that copyright notice and this permission notice appear
  15.  * in supporting documentation.
  16.  *
  17.  * Permission to modify the software is granted, but not the right to
  18.  * distribute the complete modified source code.  Modifications are to
  19.  * be distributed as patches to the released version.  Permission to
  20.  * distribute binaries produced by compiling modified sources is granted,
  21.  * provided you
  22.  *   1. distribute the corresponding source modifications from the
  23.  *    released version in the form of a patch file along with the binaries,
  24.  *   2. add special version identification to distinguish your version
  25.  *    in addition to the base release version number,
  26.  *   3. provide your name and address as the primary contact for the
  27.  *    support of your modified version, and
  28.  *   4. retain our contact information in regard to use of the base
  29.  *    software.
  30.  * Permission to distribute the released version of the source code along
  31.  * with corresponding source modifications in the form of a patch file is
  32.  * granted with same provisions 2 through 4 for binary distributions.
  33.  *
  34.  * This software is provided "as is" without express or implied warranty
  35.  * to the extent permitted by applicable law.
  36. ]*/
  37.  
  38.  
  39. /* This module collects various functions, which were previously scattered
  40.  * all over the place. In a future implementation of gnuplot, each of
  41.  * these functions will probably reside in their own file in a subdirectory.
  42.  * - Lars Hecking
  43.  */
  44.  
  45. #include "plot.h"
  46.  
  47. /*
  48.  * ANSI C functions
  49.  */
  50.  
  51. /* memcpy() */
  52.  
  53. #ifdef NO_MEMCPY
  54. # ifndef HAVE_BCOPY
  55. /*
  56.  * cheap and slow version of memcpy() in case you don't have one 
  57.  */
  58. int memcpy __PROTO((char *, char *, size_t));
  59.  
  60. int
  61. memcpy (dest, src, len)
  62.      char *dest, *src;
  63.      size_t len;
  64. {
  65.   while (len--)
  66.     *dest++ = *src++;
  67. }
  68. # endif /* !HAVE_BCOPY */
  69. #endif /* NO_MEMCPY */
  70.  
  71. /* strchr()
  72.  * Simple and portable version, conforming to Plauger.
  73.  * Would this be more efficient as a macro?
  74.  */
  75. #ifdef NO_STRCHR
  76. # ifndef HAVE_INDEX
  77. char *strchr __PROTO((const char *, int));
  78.  
  79. char *
  80. strchr (s, c)
  81.      const char *s;
  82.      int c;
  83. {
  84.   do {
  85.     if (*s == (char)c)
  86.       return s;
  87.   } while (*s++ != (char)0);
  88.  
  89.   return NULL;
  90. }
  91. # endif /* !HAVE_INDEX */
  92. #endif /* NO_STRCHR */
  93.  
  94.  
  95. /* memset () 
  96.  *
  97.  * Since we want to use memset, we have to map a possibly nonzero fill byte
  98.  * to the bzero function. The following defined might seem a bit odd, but I
  99.  * think this is the only possible way.
  100.  */
  101.  
  102. #ifdef NO_MEMSET
  103. # ifdef HAVE_BZERO
  104. #  define memset(s, b, l) \
  105. do {                      \
  106.   assert((b)==0);         \
  107.   bzero((s), (l));        \
  108. } while(0)
  109. #  else
  110. #  error You must have either memset or bzero
  111. # endif /* HAVE_BZERO */
  112. #endif /* NO_MEMSET */
  113.  
  114.  
  115. /* strerror() */
  116. #ifdef NO_STRERROR
  117.  
  118. extern int sys_nerr;
  119. extern char *sys_errlist[];
  120.  
  121. char *strerror __PROTO((int));
  122.  
  123. char *strerror(no)
  124. int no;
  125. {
  126.   static char res_str[30];
  127.  
  128.   if(no>sys_nerr) {
  129.     sprintf(res_str, "unknown errno %d", no);
  130.     return res_str;
  131.   } else {
  132.     return sys_errlist[no];
  133.   }
  134. }
  135. #endif /* NO_STRERROR */
  136.  
  137.  
  138. /* strstr() */
  139. #ifdef NO_STRSTR
  140. char *strstr __PROTO((const char *, const char *));
  141.  
  142. char *strstr (cs, ct)
  143. const char *cs, *ct;
  144. {
  145.   size_t len;
  146.  
  147.   if (!cs || !ct)
  148.     return NULL;
  149.  
  150.   if (!*ct)
  151.     return (char *)cs;
  152.   
  153.   len = strlen(ct);
  154.   while (*cs)
  155.     {
  156.       if (strncmp(cs, ct, len)==0)
  157.     return (char *)cs;
  158.       cs++;
  159.     }
  160.  
  161.   return NULL;
  162. }
  163. #endif /* NO_STRSTR */
  164.  
  165.  
  166. #ifdef __PUREC__
  167. /*
  168.  * a substitute for PureC's buggy sscanf.
  169.  * this uses the normal sscanf and fixes the following bugs:
  170.  * - whitespace in format matches whitespace in string, but doesn't
  171.  *   require any. ( "%f , %f" scans "1,2" correctly )
  172.  * - the ignore value feature works (*). this created an address error
  173.  *   in PureC.
  174.  */
  175.  
  176. #include <stdarg.h>
  177.  
  178. int purec_sscanf( const char *string, const char *format, ... )
  179. {
  180.   va_list args;
  181.   int cnt=0;
  182.   char onefmt[256];
  183.   char buffer[256];
  184.   const char *f=format;
  185.   const char *s=string;
  186.   char *f2;
  187.   char ch;
  188.   int ignore;
  189.   void *p;
  190.   int *ip;
  191.   int pos;
  192.  
  193.   va_start(args,format);
  194.   while( *f && *s ) {
  195.     ch=*f++;
  196.     if( ch!='%' ) {
  197.       if(isspace(ch)) {
  198.         /* match any number of whitespace */
  199.         while(isspace(*s)) s++;
  200.       } else {
  201.         /* match exactly the character ch */
  202.         if( *s!=ch ) goto finish;
  203.         s++;
  204.       }
  205.     } else {
  206.       /* we have got a '%' */
  207.       ch=*f++;
  208.       if( ch=='%' ) {
  209.         /* match exactly % */
  210.         if( *s!=ch ) goto finish;
  211.         s++;
  212.       } else {
  213.         f2=onefmt;
  214.         *f2++='%';
  215.         *f2++=ch;
  216.         ignore=0;
  217.         if( ch=='*' ) {
  218.           ignore=1;
  219.           ch=f2[-1]=*f++;
  220.         }
  221.         while( isdigit(ch) ) {
  222.           ch=*f2++=*f++;
  223.         }
  224.         if( ch=='l' || ch=='L' || ch=='h' ) {
  225.           ch=*f2++=*f++;
  226.         }
  227.         switch(ch) {
  228.           case '[':
  229.             while( ch && ch!=']' ) {
  230.               ch=*f2++=*f++;
  231.             }
  232.             if( !ch ) goto error;
  233.             break;
  234.           case 'e':
  235.           case 'f':
  236.           case 'g':
  237.           case 'd':
  238.           case 'o':
  239.           case 'i':
  240.           case 'u':
  241.           case 'x':
  242.           case 'c':
  243.           case 's':
  244.           case 'p':
  245.           case 'n': /* special case handled below */
  246.             break;
  247.           default:
  248.             goto error;
  249.         }
  250.         if( ch!='n' ) {
  251.           strcpy(f2,"%n");
  252.           if( ignore ) {
  253.             p=buffer;
  254.           } else {
  255.             p=va_arg(args,void *);
  256.           }
  257.           switch( sscanf( s, onefmt, p, &pos ) ) {
  258.             case EOF: goto error;
  259.             case  0 : goto finish;
  260.           }
  261.           if( !ignore ) cnt++;
  262.           s+=pos;
  263.         } else {
  264.           if( !ignore ) {
  265.             ip=va_arg(args,int *);
  266.             *ip=(int)(s-string);
  267.           }
  268.         }
  269.       }
  270.     }
  271.   }
  272.  
  273.   if( !*f ) goto finish;
  274.  
  275. error:
  276.   cnt=EOF;
  277. finish:
  278.   va_end(args);
  279.   return cnt;
  280. }
  281.  
  282. /* use the substitute now. I know this is dirty trick, but it works. */
  283. #define sscanf purec_sscanf
  284.  
  285. #endif /* __PUREC__ */
  286.  
  287.  
  288. /*
  289.  * POSIX functions
  290.  */
  291.  
  292. #ifndef HAVE_SLEEP
  293. /* The implementation below does not even come close
  294.    to what is required by POSIX.1, but I suppose
  295.    it doesn't really matter on these systems. lh
  296.  */
  297.  
  298. unsigned int sleep __PROTO((unsigned int));
  299.  
  300. #ifdef AMIGA_SC_6_1
  301. #include <proto/dos.h>
  302. #endif
  303.  
  304. #ifdef WIN32
  305. /* the WIN32 API has a Sleep function that does not consume CPU cycles */
  306. #include <windows.h>
  307. #endif
  308.  
  309. unsigned int
  310. sleep(delay)
  311.     unsigned int delay;
  312. {
  313. #if defined(MSDOS) || defined(_Windows) || defined(DOS386) || defined(AMIGA_AC_5)
  314. #if !(defined(__TURBOC__) || defined(__EMX__) || defined(DJGPP)) || defined(_Windows) /* Turbo C already has sleep() */
  315. /* kludge to provide sleep() for msc 5.1 */
  316.     unsigned long   time_is_up;
  317.  
  318.     time_is_up = time(NULL) + (unsigned long) delay;
  319.     while (time(NULL) < time_is_up)
  320.      /* wait */ ;
  321. #endif /* !__TURBOC__ ... */
  322. #endif /* MSDOS ... */
  323.  
  324. #ifdef AMIGA_SC_6_1
  325.     Delay(50 * delay);
  326. #endif
  327.  
  328. #ifdef WIN32
  329.     Sleep( (DWORD) delay*1000 );
  330. #endif
  331.  
  332.     return (unsigned int)0;
  333. }
  334. #endif                          /* HAVE_SLEEP */
  335.  
  336.  
  337. /*
  338.  * Other common functions
  339.  */
  340.  
  341. /*****************************************************************
  342.     portable implementation of strnicmp (hopefully)
  343. *****************************************************************/
  344.  
  345. #ifndef HAVE_STRNICMP
  346. # ifndef HAVE_STRNCASECMP
  347. int strnicmp __PROTO((char *, char *, int));
  348.  
  349. int strnicmp (s1, s2, n)
  350. char *s1;
  351. char *s2;
  352. int n;
  353. {
  354.     char c1,c2;
  355.  
  356.     if(n==0) return 0;
  357.  
  358.     do {
  359.     c1 = *s1++; if(islower(c1)) c1=toupper(c1);
  360.     c2 = *s2++; if(islower(c2)) c2=toupper(c2);
  361.     } while(c1==c2 && c1 && c2 && --n>0);
  362.  
  363.     if(n==0 || c1==c2) return 0;
  364.     if(c1=='\0' || c1<c2) return 1;
  365.     return -1;
  366. }
  367. # endif /* !HAVE_STRNCASECMP */
  368. #endif /* !HAVE_STRNICMP */
  369.  
  370.  
  371. /* Safe, '\0'-terminated version of strncpy()
  372.  * safe_strncpy(dest, src, n), where n = sizeof(dest)
  373.  * This is basically the old fit.c(copy_max) function
  374.  */
  375.  
  376. char *safe_strncpy(d, s, n)
  377. char *d, *s;
  378. size_t n;
  379. {
  380.     char *ret;
  381.  
  382.     ret = strncpy(d, s, n);
  383.     if (strlen(s) >= n)
  384.     d[ n > 0 ? n-1 : 0] = NUL;
  385.  
  386.     return ret;
  387. }
  388.  
  389.